var base32 = require('./base32');


var default_options = {
    timestampBits: 40,
    shardBits: 12,
    lowBits: 12,
    totalBits: 64,
    prefix: "",
    epoch: new Date(2015, 1, 1),
    shard: 0
};


function pack(bits) {
    var len = bits.length / 8;
    var result = "";
    for (var i = 0; i < len; i++) {
        var l = parseInt(bits.slice(i * 8, i * 8 + 8), 2);
        result += String.fromCharCode(l)
    }
    return result;
};


function fillzero(d, length) {
    if (d.length > length) {
        return d.slice((d.length - length), d.length);
    }
    return Array(length - d.length).join("0") + d;
}

module.exports.init = function (options) {
    var opt = default_options;
    if (opt) {
        for (var p in options) {
            if (options.hasOwnProperty(p)) {
                opt[p] = options[p]
            }
        }
    }

    return {
        low: 0,
        next: function () {
            this.low = this.low + 1;
            var ts = Date.now() - opt.epoch.getTime();
            var high = fillzero(ts.toString(2), opt.timestampBits);
            var shard = fillzero(opt.shard.toString(2), opt.shardBits);
            var low = fillzero(this.low.toString(2), opt.lowBits);
            var full = high + shard + low;
            if (opt.prefix) {
                return opt.prefix + "_" + base32.encode(pack(full))
            } else {
                return base32.encode(pack(full))
            }
        }

    }
};